// file: include/os/softirq.h
// autor: jiangxinpeng
// time: 2021.3.21
// copyright: (C) copyright by jiangxinpeng,All right are reserved.

#ifndef OS_SOFTIRQ_H
#define OS_SOFTIRQ_H

#include <arch/atomic.h>
#include <lib/list.h>

typedef enum
{
    HIGHTASK_ASSIGT_SOFTIRQ = 0,
    TIMER_SOFTIRQ,
    NET_TX_SOFTIRQ,
    NET_RX_SOFTIRQ,
    TASK_ASSIGT_SOFTIRQ,
    SCHED_SOFTIRQ,
    RCU_SOFTIRQ,
    MAX_SOFTIRQ
} softirq_t;

typedef void (*softirq_action_t)();

#define TASK_ASSIGT_SCHED 0

typedef void (*task_assigt_fun_t)(uint32_t);

typedef struct task_assigt
{
    list_t list;           // list
    uint32_t status;       // status
    atomic_t enable;       // control task assigt enable or disable
    task_assigt_fun_t fun; // function
    uint32_t data;         // argument
} task_assigt_t;

static inline void TaskAssigtInit(task_assigt_t *assigt, task_assigt_fun_t fun, uint32_t data)
{
    list_init(&assigt->list);
    assigt->status = 0;
    assigt->fun = fun;
    assigt->data = data;
    AtomicSet(&assigt->enable, 0);
}

static inline void TaskAssigtDisable(task_assigt_t *assigt)
{
    AtomicSet(&assigt->enable, 1);
}

static inline void TaskAssigtEnable(task_assigt_t *assigt)
{
    AtomicSet(&assigt->enable, 0);
}

#define TASK_ASSIGT_INIT(name, fun, data)                      \
    {                                                          \
        LIST_HEAD_INIT(name.list), 0, AtomicInit(0), fun, data \
    }
#define DEFINE_TASK_ASSIGT(name, fun, data) \
    task_assigt_t name = TASK_ASSIGT_INIT(name)

void SoftIrqInit();
void SoftirqBuild(uint64_t softirq, softirq_action_t action);
void SoftirqActive(uint64_t softirq);
void SoftIrqHandle();

#endif